<template>
  <div class="multi-image-upload">
    <h2>多图片上传示例</h2>

    <!-- 上传区域 -->
    <div class="upload-area"
         @drop.prevent="handleDrop"
         @dragover.prevent="handleDragOver"
         @dragleave.prevent="handleDragLeave"
         :class="{ 'drag-over': isDragOver }">
      
      <!-- 图片列表 -->
      <div class="image-list">
        <div v-for="(image, index) in imageList" 
             :key="index"
             class="image-item"
             :class="{ 'is-uploading': image.status === 'uploading' }">
          <!-- 图片展示 -->
          <div class="image-preview">
            <img v-if="image.url" :src="image.url" :alt="image.name">
            <div v-else class="image-placeholder">
              <i class="el-icon-picture-outline"></i>
            </div>
            <!-- 上传状态遮罩 -->
            <div v-if="image.status === 'uploading'" class="upload-mask">
              <i class="el-icon-loading"></i>
              <span>上传中...</span>
            </div>
            <div v-if="image.status === 'error'" class="error-mask">
              <i class="el-icon-warning"></i>
              <span>{{ image.error }}</span>
            </div>
          </div>
          
          <!-- 图片信息 -->
          <div class="image-info">
            <div class="image-name" :title="image.name">{{ image.name }}</div>
            <div class="image-size">{{ formatFileSize(image.size) }}</div>
          </div>
          
          <!-- 操作按钮 -->
          <div class="image-actions">
            <template v-if="image.status === 'error'">
              <span class="error-text">
                <i class="el-icon-warning"></i>
                {{ image.error }}
              </span>
            </template>
            <el-button type="text" size="mini" @click="removeImage(index)">
              <i class="el-icon-delete"></i>
            </el-button>
          </div>
        </div>

        <!-- 添加图片按钮 -->
        <div class="image-upload-trigger" 
             v-if="imageList.length < maxImages"
             @click="triggerUpload">
          <i class="el-icon-plus"></i>
          <div class="upload-text">添加图片</div>
          <input
            ref="fileInput"
            type="file"
            multiple
            accept="image/*"
            @change="handleFileChange"
            style="display: none"
          >
        </div>
      </div>
    </div>

    <!-- 上传提示 -->
    <div class="upload-tips">
      <p>支持jpg、png格式，单张图片不超过5MB，最多可上传{{ maxImages }}张</p>
      <p>可拖拽图片到此处，或点击添加按钮选择图片</p>
    </div>

    <!-- 批量上传按钮 -->
    <div class="batch-actions" v-if="imageList.length > 0">
      <template v-if="hasUnuploadedImages">
        <el-button 
          type="primary" 
          @click="uploadAllImages" 
          :loading="isUploading"
          :disabled="!hasReadyImages">
          {{ uploadButtonText }}
        </el-button>
      </template>
      <el-button @click="clearImages" :disabled="isUploading">
        清空列表
      </el-button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'MultiImageUpload',
  
  data() {
    return {
      imageList: [],
      isDragOver: false,
      maxImages: 9,
      acceptedTypes: ['image/jpeg', 'image/png', 'image/gif'],
      maxSize: 5 * 1024 * 1024, // 5MB
      isUploading: false,
      uploadedCount: 0
    };
  },

  computed: {
    hasReadyImages() {
      return this.imageList.some(img => 
        img.status === 'ready' || img.status === 'error'
      );
    },

    hasUnuploadedImages() {
      return this.imageList.some(img => 
        img.status !== 'success'
      );
    },

    uploadButtonText() {
      if (this.isUploading) {
        return `正在上传(${this.uploadedCount}/${this.getUnuploadedCount()})`;
      }
      return '开始上传';
    }
  },

  methods: {
    triggerUpload() {
      this.$refs.fileInput.click();
    },

    handleFileChange(e) {
      const files = Array.from(e.target.files);
      this.processFiles(files);
      // 清空input的值，允许重复选择同一文件
      e.target.value = '';
    },

    handleDrop(e) {
      this.isDragOver = false;
      const files = Array.from(e.dataTransfer.files).filter(file => 
        this.acceptedTypes.includes(file.type)
      );
      this.processFiles(files);
    },

    handleDragOver() {
      this.isDragOver = true;
    },

    handleDragLeave() {
      this.isDragOver = false;
    },

    processFiles(files) {
      const remainingSlots = this.maxImages - this.imageList.length;
      const filesToProcess = files.slice(0, remainingSlots);

      filesToProcess.forEach(file => {
        if (this.validateFile(file)) {
          this.addImage(file);
        }
      });
    },

    validateFile(file) {
      if (!this.acceptedTypes.includes(file.type)) {
        this.$message.error(`${file.name} 不是支持的图片格式`);
        return false;
      }
      
      if (file.size > this.maxSize) {
        this.$message.error(`${file.name} 超过5MB限制`);
        return false;
      }

      return true;
    },

    addImage(file) {
      if (this.imageList.length >= this.maxImages) {
        this.$message.warning(`最多只能上传${this.maxImages}张图片`);
        return;
      }

      const reader = new FileReader();
      reader.onload = (e) => {
        this.imageList.push({
          file: file,
          name: file.name,
          size: file.size,
          url: e.target.result,
          status: 'ready',
          error: null
        });
      };
      reader.readAsDataURL(file);
    },

    async uploadAllImages() {
      if (this.isUploading) return;
      
      this.isUploading = true;
      this.uploadedCount = 0;

      try {
        const pendingImages = this.imageList.filter(img => 
          img.status !== 'success'
        );

        if (pendingImages.length === 0) {
          this.$message.warning('没有需要上传的图片');
          return;
        }

        const formData = new FormData();
        pendingImages.forEach((image) => {
          formData.append('images', image.file);
        });

        formData.append('totalCount', pendingImages.length);

        try {
          await new Promise((resolve, reject) => {
            pendingImages.forEach(image => {
              image.status = 'uploading';
              image.error = null;
            });

            setTimeout(() => {
              if (Math.random() > 0.3) {
                pendingImages.forEach(image => {
                  image.status = 'success';
                  this.uploadedCount++;
                });
                resolve();
              } else {
                pendingImages.forEach(image => {
                  image.status = 'error';
                  image.error = '批量上传失败';
                });
                reject(new Error('批量上传失败，请重试'));
              }
            }, 2000);
          });

          this.$message.success('图片上传成功');
        } catch (error) {
          this.$message.error(error.message);
          throw error;
        }

      } catch (error) {
        console.error('批量上传出错:', error);
      } finally {
        this.isUploading = false;
      }
    },

    clearImages() {
      this.imageList = [];
      this.uploadedCount = 0;
    },

    removeImage(index) {
      this.imageList.splice(index, 1);
    },

    formatFileSize(bytes) {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
    },

    handleKeyDown(e) {
      if (!this.previewVisible) return;
      
      switch(e.key) {
        case 'ArrowLeft':
          this.prevImage();
          break;
        case 'ArrowRight':
          this.nextImage();
          break;
        case 'Escape':
          this.previewVisible = false;
          break;
      }
    },

    getUnuploadedCount() {
      return this.imageList.filter(img => 
        img.status !== 'success'
      ).length;
    }
  },

  mounted() {
    window.addEventListener('keydown', this.handleKeyDown);
  },

  beforeDestroy() {
    window.removeEventListener('keydown', this.handleKeyDown);
  }
};
</script>

<style scoped>
.multi-image-upload {
  padding: 20px;
}

h2 {
  color: #2c3e50;
  margin-bottom: 20px;
}

.upload-area {
  border: 2px dashed #dcdfe6;
  border-radius: 8px;
  padding: 20px;
  background: #fff;
  transition: all 0.3s;
}

.upload-area.drag-over {
  border-color: #409eff;
  background: #ecf5ff;
}

.image-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 20px;
}

.image-item {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  overflow: hidden;
  transition: all 0.3s;
}

.image-item:hover {
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.image-preview {
  position: relative;
  width: 100%;
  height: 150px;
  background: #f5f7fa;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.image-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.image-placeholder {
  color: #909399;
  font-size: 24px;
}

.upload-mask,
.error-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #fff;
}

.upload-mask i,
.error-mask i {
  font-size: 24px;
  margin-bottom: 8px;
}

.image-info {
  padding: 10px;
  background: #fff;
}

.image-name {
  font-size: 14px;
  color: #303133;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.image-size {
  font-size: 12px;
  color: #909399;
}

.image-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 10px;
  background: #f8f9fa;
}

.image-upload-trigger {
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 150px;
  transition: all 0.3s;
}

.image-upload-trigger:hover {
  border-color: #409eff;
  color: #409eff;
}

.upload-text {
  margin-top: 8px;
  font-size: 14px;
  color: #606266;
}

.upload-tips {
  margin-top: 10px;
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
}

.batch-actions {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  gap: 10px;
}

.batch-actions .el-button--success {
  width: 100%;
  max-width: 300px;
}

.error-text {
  color: #f56c6c;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.image-item.upload-success {
  border-color: #67c23a;
}

.image-item.upload-success .image-preview::after {
  content: '✓';
  position: absolute;
  top: 10px;
  right: 10px;
  width: 20px;
  height: 20px;
  background: #67c23a;
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
}
</style> 